package tfts

import (
	"fmt"
	"strings"
)

type fighter struct {
	health     int
	armor      int
	dmgTaken   int
	omnivamp   int // 全能吸血
	healthAmp  int
	recoverAmp int
	shieldAmp  int
	healAmp    int
	hitRecover int
}

type attrMeta struct {
	*fighter
	key        string
	factor     int     // 倍数，默认100
	ad         int     // 攻击力
	ap         int     // 法强
	as         int     // 攻速
	ae         int     // 附带特效伤害
	adAmp      int     // ad总加成,蓝buff
	apAmp      int     // ap总加成,蓝buff
	strike     int     // 触发双重打击的概率
	amp        int     // 伤害增幅，基础为100
	atkAmp     int     // 普攻增幅，基础为100，金克斯火箭，泽丽镜像，月男炮台，凯隐旋转
	castAmp    int     // 施法增幅，基础为100
	unqAmp     int     // 独立乘区的增幅，基础为0
	critChance int     // 暴击率，基础25
	critAmp    int     // 暴击伤害增幅，基础40
	skillCrit  bool    // 是否技能暴击
	hitMana    int     // 攻击回复法力值
	regen      float64 // 每秒回蓝量
	manaAmp    float64 // 法力来源增幅，基础为0
	manaShrink float64 // 减少的最大魔法值，单位为百分比
	manaDec    int     // 减少的最大魔法值，单位为1mana
}

func HitMana(i int) *attrMeta {
	return &attrMeta{hitMana: i, factor: 100}
}

func Regen(i float64) *attrMeta {
	return &attrMeta{regen: i, factor: 100}
}

func AE(i int) *attrMeta {
	return &attrMeta{ae: i, factor: 100}
}

func DoubleStrike(i int) *attrMeta {
	return &attrMeta{strike: i, factor: 100}
}

func AtkAmp(i int) *attrMeta {
	return &attrMeta{atkAmp: i, factor: 100}
}

func CastAmp(i int) *attrMeta {
	return &attrMeta{castAmp: i, factor: 100}
}

func UnqAmp(i int) *attrMeta {
	return &attrMeta{unqAmp: i, factor: 100}
}

func ManaAmp(i float64) *attrMeta {
	return &attrMeta{manaAmp: (100 + i) / 100, factor: 100}
}

func ManaShrink(i float64) *attrMeta {
	return &attrMeta{manaShrink: (100 - i) / 100, factor: 100}
}

func ManaDec(i int) *attrMeta {
	return &attrMeta{manaDec: i, factor: 100}
}

func AD(i int) *attrMeta {
	return &attrMeta{ad: i, factor: 100}
}

func AP(i int) *attrMeta {
	return &attrMeta{ap: i, factor: 100}
}

func AdAmp(i int) *attrMeta {
	return &attrMeta{adAmp: i, factor: 100}
}

func ApAmp(i int) *attrMeta {
	return &attrMeta{apAmp: i, factor: 100}
}

func AS(i int) *attrMeta {
	return &attrMeta{as: i, factor: 100}
}

func AMP(i int) *attrMeta {
	return &attrMeta{amp: i, factor: 100}
}

func HP(i int) *attrMeta {
	return &attrMeta{fighter: &fighter{health: i}, factor: 100}
}

func HpAmp(i int) *attrMeta {
	return &attrMeta{fighter: &fighter{healthAmp: i}, factor: 100}
}

func AR(i int) *attrMeta {
	return &attrMeta{fighter: &fighter{armor: i}, factor: 100}
}

func DR(i int) *attrMeta {
	return &attrMeta{fighter: &fighter{dmgTaken: 100 - i}, factor: 100}
}

func OMP(i int) *attrMeta {
	return &attrMeta{fighter: &fighter{omnivamp: i}, factor: 100}
}

func Hit(i int) *attrMeta {
	return &attrMeta{fighter: &fighter{hitRecover: i}, factor: 100}
}

// 技能暴击
func Critable() *attrMeta {
	return &attrMeta{skillCrit: true, factor: 100}
}

func CritRate(i int) *attrMeta {
	return &attrMeta{critChance: i, factor: 100}
}

func CritAmp(i int) *attrMeta {
	return &attrMeta{critAmp: i, factor: 100}
}

func (am *attrMeta) String() string {
	if len(am.key) != 0 {
		return am.key
	}

	sb := strings.Builder{}

	if am.isFighter() {
		// 处理 fighter 字段
		if am.health != 0 {
			sb.WriteString(fmt.Sprintf("Hp%d,", am.health))
		}
		if am.armor != 0 {
			sb.WriteString(fmt.Sprintf("Ar%d,", am.armor))
		}
		if am.dmgTaken != 0 {
			sb.WriteString(fmt.Sprintf("Dr%d,", 100-am.dmgTaken))
		}
		if am.healthAmp != 0 {
			sb.WriteString(fmt.Sprintf("HpAmp%d,", am.healthAmp))
		}
		if am.recoverAmp != 0 {
			sb.WriteString(fmt.Sprintf("RecoverAmp%d,", am.recoverAmp))
		}
		if am.shieldAmp != 0 {
			sb.WriteString(fmt.Sprintf("ShieldAmp%d,", am.shieldAmp))
		}
		if am.healAmp != 0 {
			sb.WriteString(fmt.Sprintf("HealAmp%d,", am.healAmp))
		}
		if am.hitRecover != 0 {
			sb.WriteString(fmt.Sprintf("HitRecover%d,", am.hitRecover))
		}
	}

	// 处理 attributes 字段
	if am.factor != 100 {
		sb.WriteString(fmt.Sprintf("Fac%d,", am.factor))
	}
	if am.ad != 0 {
		sb.WriteString(fmt.Sprintf("Ad%d,", am.ad*am.factor/100))
	}
	if am.ap != 0 {
		sb.WriteString(fmt.Sprintf("Ap%d,", am.ap*am.factor/100))
	}
	if am.as != 0 {
		sb.WriteString(fmt.Sprintf("As%d,", am.as*am.factor/100))
	}
	if am.ae != 0 {
		sb.WriteString(fmt.Sprintf("Ae%d,", am.ae*am.factor/100))
	}
	if am.strike != 0 {
		sb.WriteString(fmt.Sprintf("Strike%d,", am.strike))
	}
	if am.amp != 0 {
		sb.WriteString(fmt.Sprintf("Amp%d,", am.amp))
	}
	if am.atkAmp != 0 {
		sb.WriteString(fmt.Sprintf("AtkAmp%d,", am.atkAmp))
	}
	if am.castAmp != 0 {
		sb.WriteString(fmt.Sprintf("CastAmp%d,", am.castAmp))
	}
	if am.unqAmp != 0 {
		sb.WriteString(fmt.Sprintf("UnqAmp%d,", am.unqAmp))
	}
	if am.critChance != 0 {
		sb.WriteString(fmt.Sprintf("CC%d,", am.critChance))
	}
	if am.critAmp != 0 {
		sb.WriteString(fmt.Sprintf("CritAmp%d,", am.critAmp))
	}
	if am.skillCrit {
		sb.WriteString("SkillCrit")
	}
	if am.hitMana != 0 {
		sb.WriteString(fmt.Sprintf("HitMana%d,", am.hitMana))
	}
	if am.regen != 0 {
		sb.WriteString(fmt.Sprintf("Regen%.1f,", am.regen))
	}
	if am.manaAmp >= 0 {
		sb.WriteString(fmt.Sprintf("ManaAmp%.0f,", am.manaAmp*100))
	}

	// 检查并清除最后一个字符为逗号的情况
	if sb.Len() > 0 {
	}

	am.key = sb.String()

	if len(am.key) > 0 && am.key[len(am.key)-1] == ',' {
		am.key = am.key[:len(am.key)-1]
	}

	return am.key
}

func (am *attrMeta) Add(src *attrMeta) *attrMeta {
	if src.factor <= 0 {
		return am
	}
	if src.factor == 0 {
		src.factor = 100
	}
	if src.isFighter() && am.isFighter() {
		am.health += src.health * src.factor / 100
		am.armor += src.armor * src.factor / 100
		if am.dmgTaken == 0 {
			am.dmgTaken = src.dmgTaken
		} else if src.dmgTaken > 0 {
			am.dmgTaken = am.dmgTaken * src.dmgTaken / 100
		}
		am.omnivamp += src.omnivamp * src.factor / 100
		am.healthAmp += src.healthAmp * src.factor / 100
		am.healAmp += src.healAmp * src.factor / 100
		am.shieldAmp += src.shieldAmp * src.factor / 100
		am.recoverAmp += src.recoverAmp * src.factor / 100
		am.hitRecover += src.hitRecover * src.factor / 100
	}
	am.ad += src.ad * src.factor / 100
	am.ap += src.ap * src.factor / 100
	am.adAmp += src.adAmp * src.factor / 100
	am.apAmp += src.apAmp * src.factor / 100
	am.as += src.as * src.factor / 100
	am.ae += src.ae * src.factor / 100
	am.strike += src.strike * src.factor / 100
	am.amp += src.amp * src.factor / 100
	am.atkAmp += src.atkAmp * src.factor / 100
	am.castAmp += src.castAmp * src.factor / 100
	am.unqAmp += src.unqAmp * src.factor / 100
	am.critChance += src.critChance * src.factor / 100
	am.critAmp += src.critAmp * src.factor / 100
	am.hitMana += src.hitMana * src.factor / 100
	am.regen += src.regen * float64(src.factor/100)
	if src.manaAmp > 0 {
		am.manaAmp = max(1.0, am.manaAmp)
		am.manaAmp *= src.manaAmp * float64(src.factor) / 100
	}
	if src.manaShrink > 0 {
		if am.manaShrink <= 1e-3 {
			am.manaShrink = 1.0
		}
		am.manaShrink *= am.manaShrink * src.manaShrink * float64(src.factor) / 100
	}
	am.manaDec += src.manaDec * src.factor / 100
	am.skillCrit = am.skillCrit || src.skillCrit
	return am
}

func (am *attrMeta) stat() *attrMeta {
	return am
}

func (am *attrMeta) valid() bool {
	return true
}

func (am *attrMeta) isFighter() bool {
	return am.fighter != nil
}
